<?php
namespace tonyWa\lklPay\model;
use tonyWa\lklPay\model\{BaseRequestVO,LabsOrderPreOrderPayReq,TermExtInfo};
class Lakala {

    private $appid;
    private $mchSerialNo;
    private $mercId;
    private $termNo;
    private $merchantPrivateKeyPath;
    private $lklCertificatePath;
    private $subject;
    private $schema = 'LKLAPI-SHA256withRSA';
    private $version = '1.0.0';
    private $exterOrderSource = 'OS10000071';

    public function __construct($params) {
        $this->appid                    = $params['appid'];
        $this->mchSerialNo              = $params['mchSerialNo'];
        $this->mercId                   = $params['mercId'];
        $this->termNo                   = $params['termNo'];
        $this->merchantPrivateKeyPath   = $params['merchantPrivateKeyPath'];
        $this->lklCertificatePath       = $params['lklCertificatePath'];
        $this->subject                  = $params['subject'] ?? '奥式生活订单';
    }

    /**
     * @return void
     * 测试
     */
    public function test(){
        echo "hello,composer";
    }
	public function wechat() {
        $reqInfo = new LabsOrderPreOrderPayReq();
        $reqInfo->mercId = '822162070120015';
        $reqInfo->termNo = '47827142';
        $reqInfo->payMode = 'ALIPAY';
        $reqInfo->openId = 'olpr-0pHIp1AjaAr29LENlHi0cJ0';
        $reqInfo->amount = 1;
        $reqInfo->spbillCreateIp = '127.0.0.1';
        $reqInfo->transType = '41';
        $reqInfo->orderId = '2020072915yhl142212';
        $reqInfo->appId = 'wx9ef39b708f16694d';
        $reqInfo->subject = '奥式生活订单';
        $reqInfo->exterOrderSource = 'OS10000071';

        $termExtInfo = new TermExtInfo();
        $termExtInfo->termLoc = '';

        $baseRequestVO = new BaseRequestVO();
        $baseRequestVO->reqData = $reqInfo;
        $baseRequestVO->termExtInfo = $termExtInfo;
        $baseRequestVO->timestamp = time();
        $baseRequestVO->ver = $this->version;

        return json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);
    }

    //支付宝
    public function aliPay($orderId, $amount) {
        $reqInfo = new LabsOrderPreOrderPayReq();
        $reqInfo->mercId = $this->mercId;
        $reqInfo->termNo = $this->termNo;
        $reqInfo->payMode = 'ALIPAY';
        // $reqInfo->openId = 'olpr-0pHIp1AjaAr29LENlHi0cJ0';
        $reqInfo->amount = $amount * 100;
        $reqInfo->spbillCreateIp = '127.0.0.1';
        $reqInfo->transType = '41';
        $reqInfo->orderId = $orderId;
        // $reqInfo->appId = 'wx9ef39b708f16694d';
        $reqInfo->subject = $this->subject;
        $reqInfo->exterOrderSource = $this->exterOrderSource;

        $termExtInfo = new TermExtInfo();
        // $termExtInfo->termLoc = '+155621.316,-125622.12';

        $baseRequestVO = new BaseRequestVO();
        $baseRequestVO->reqData = $reqInfo;
        $baseRequestVO->termExtInfo = $termExtInfo;
        $baseRequestVO->timestamp = random(8);
        $baseRequestVO->ver = $this->version;

        $body = json_encode($baseRequestVO, JSON_UNESCAPED_UNICODE);

        $authorization = $this->getAuthorization($body);

        return $this->post(LKL_ORDERPAY_URL . '/labs_order_pre_orderpay', $body, $authorization);
    }

    //验签
    public function signatureVerification($authorization, $body) {
        $authorization = str_replace($this->schema . " ", "", $authorization);
        $authorization = str_replace(",","&", $authorization);
        $authorization = str_replace("\"","", $authorization);
        $authorization = $this->convertUrlQuery($authorization);

        $authorization['signature'] = base64_decode($authorization['signature']);

        $message = $authorization['timestamp'] . "\n" . $authorization['nonce_str'] . "\n" . $body . "\n";

        $key = openssl_get_publickey(file_get_contents($this->lklCertificatePath));
        $flag = openssl_verify($message, $authorization['signature'], $key, OPENSSL_ALGO_SHA256);
        openssl_free_key($key);
        if($flag) {
            return true;
        }
        return false;
    }

	//签名
	public function getAuthorization($body) {
		$nonceStr = random(8);
     	$timestamp = time();

      	$message = $this->appid . "\n" . $this->mchSerialNo . "\n" . $timestamp . "\n" . $nonceStr . "\n" . $body . "\n";

		$key = openssl_get_privatekey(file_get_contents($this->merchantPrivateKeyPath));

        openssl_sign($message, $signature, $key, OPENSSL_ALGO_SHA256);
        openssl_free_key($key);

        return $this->schema . " appid=\"" . $this->appid . "\"," . "serial_no=\"" . $this->mchSerialNo . "\"," . "timestamp=\"" . $timestamp . "\"," . "nonce_str=\"" . $nonceStr . "\"," . "signature=\"" . base64_encode($signature) . "\"";
	}

    //请求
    public function post($url, $data, $authorization) {

        $headers = [
            "Authorization: " . $authorization,
            "Accept: application/json",
            "Content-Type:application/json",
        ];

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);//设置HTTP头
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, 1);
        $res = curl_exec($ch);
        curl_close($ch);

        return json_decode($res, 1);
    }

    //签名参数转数组
    private function convertUrlQuery($query) {
        $queryParts = explode('&', $query);

        $params = array();
        foreach ($queryParts as $param) {
            $item = explode('=', $param);
            $params[$item[0]] = $item[1];
        }
        if($params['signature']) {
            $params['signature'] = substr($query, strrpos($query, 'signature=') + 10);
        }

        return $params;
    }


}










